package com.tengju.bff.application.wx;

import com.tengju.bff.domain.shared.JsonUtil;
import com.tengju.data.domain.model.user.StarLevelEnum;
import com.tengju.data.domain.model.wx.WxUserInfo;
import com.tengju.data.domain.model.wx.WxUserInfoRepository;
import com.tengju.support.domain.model.wx.TagId;
import com.tengju.support.domain.model.wx.TagUser;
import com.tengju.support.domain.model.wx.WechatSimpleUserInfo;
import com.tengju.support.domain.service.WeiXinCompanyService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @author: 李大仙
 * @date: 2021/11/5 11:04 上午
 */
@Service
@Slf4j
@RequiredArgsConstructor(onConstructor_ = {@Autowired})
public class WxUserTagsJobService {

    private final WxUserInfoRepository wxUserInfoRepository;
    private final WeiXinCompanyService weiXinCompanyService;

    private final String WX_STAR_LEVEL_TAG_PRE = "StarLevel_";

    @Value("#{${weixin.work.tag.map}}")
    private Map<String, Long> weixinTagMap;

    public void execute() {
        List<Long> allStarLevelTagIdList = getAllStarLevelTagIdList();
        List<WxUserInfo> wxUserInfoList = wxUserInfoRepository.selectAllServiceStar();
        Map<Long, List<Long>> idCodeTagIdsMap = getIdCodeTagIdsMap();
        List<Long> multiTagIdList = new ArrayList<>();

        for (WxUserInfo wxUserInfo : wxUserInfoList) {
            long idCode = wxUserInfo.getIdCode().getValue();
            try {
                List<Long> currentTagIdList = wxUserInfo.getTagIdList();

                Long currentStarLevelTagId = weixinTagMap.get(WX_STAR_LEVEL_TAG_PRE + wxUserInfo.getStarLevel().getCode());

                List<Long> idCodeTagIdList = idCodeTagIdsMap.get(idCode);

                List<Long> otherStarLevelTagIdList = getOtherStarLevelTagIdList(idCodeTagIdList, currentStarLevelTagId, allStarLevelTagIdList);
                List<Long> otherCurrentStarLevelTagIdList = getOtherStarLevelTagIdList(currentTagIdList, currentStarLevelTagId, allStarLevelTagIdList);

                for (Long tagId : otherStarLevelTagIdList) {
                    weiXinCompanyService.deleteTagUsers(
                            new TagId(tagId),
                            List.of(wxUserInfo.getIdCode().toString()),
                            new ArrayList<>());
                    currentTagIdList.remove(tagId);
                }

                for (Long tagId : otherCurrentStarLevelTagIdList) {
                    currentTagIdList.remove(tagId);
                }

                if (CollectionUtils.isEmpty(idCodeTagIdList)) {
                    addTag(wxUserInfo, currentTagIdList, currentStarLevelTagId);
                } else {
                    if (!idCodeTagIdList.contains(currentStarLevelTagId)) {
                        addTag(wxUserInfo, currentTagIdList, currentStarLevelTagId);
                    }
                    // 用户多等级标签
                    if (idCodeTagIdList.size() > 1) {
                        multiTagIdList.add(idCode);
                    }
                }
                wxUserInfo.setTagIdList(currentTagIdList);
                wxUserInfoRepository.updateTags(wxUserInfo);
            } catch (Exception e) {
                log.error("idCode: {}, update tags error", idCode, e);
            }
        }

        if (!CollectionUtils.isEmpty(multiTagIdList)) {
            log.info("multiTagIdList: {}", JsonUtil.toJSONString(multiTagIdList));
        }
    }

    private List<Long> getOtherStarLevelTagIdList(List<Long> idCodeTagIdList, Long currentStarLevelTagId, List<Long> allStarLevelTagIdList) {
        List<Long> result = new ArrayList<>();
        if (CollectionUtils.isEmpty(idCodeTagIdList)) {
            return result;
        }
        List<Long> tagIdList = new ArrayList<>(idCodeTagIdList);
        tagIdList.remove(currentStarLevelTagId);
        for (Long tagId : tagIdList) {
            if (allStarLevelTagIdList.contains(tagId)) {
                result.add(tagId);
            }
        }
        return result;
    }

    private Map<Long, List<Long>> getIdCodeTagIdsMap() {
        Map<Long, List<Long>> idCodeTagIdsMap = new HashMap<>();
        List<Long> tagIdList = new ArrayList<>();
        for (StarLevelEnum starLevelEnum : StarLevelEnum.values()) {
            Long currentStarLevelTagId = weixinTagMap.get(WX_STAR_LEVEL_TAG_PRE + starLevelEnum.getCode());
            if (currentStarLevelTagId != null) {
                tagIdList.add(currentStarLevelTagId);
            }
        }
        for (Long tagId : tagIdList) {
            TagUser tagUsers = weiXinCompanyService.getTagUsers(new TagId(tagId));
            List<WechatSimpleUserInfo> userList = tagUsers.getUserList();
            for (WechatSimpleUserInfo wechatSimpleUserInfo : userList) {
                if (idCodeTagIdsMap.containsKey(Long.parseLong(wechatSimpleUserInfo.getUserId()))) {
                    List<Long> userTagIdList = idCodeTagIdsMap.get(Long.parseLong(wechatSimpleUserInfo.getUserId()));
                    userTagIdList.add(tagId);
                } else {
                    List<Long> userTagIdList = new ArrayList<>();
                    userTagIdList.add(tagId);
                    idCodeTagIdsMap.put(Long.parseLong(wechatSimpleUserInfo.getUserId()), userTagIdList);
                }
            }
        }
        return idCodeTagIdsMap;
    }

    private void addTag(WxUserInfo wxUserInfo, List<Long> tagIdList, Long currentStarLevelTagId) {
        weiXinCompanyService.addTagUsers(
                new TagId(currentStarLevelTagId),
                List.of(wxUserInfo.getIdCode().toString()),
                new ArrayList<>());
        if (!tagIdList.contains(currentStarLevelTagId)) {
            tagIdList.add(currentStarLevelTagId);
        }
    }

    private List<Long> getAllStarLevelTagIdList() {
        List<Long> result = new ArrayList<>();
        result.add(weixinTagMap.get(WX_STAR_LEVEL_TAG_PRE + StarLevelEnum.CITY_STAR_ONE.getCode()));
        result.add(weixinTagMap.get(WX_STAR_LEVEL_TAG_PRE + StarLevelEnum.CITY_STAR_TWO.getCode()));
        result.add(weixinTagMap.get(WX_STAR_LEVEL_TAG_PRE + StarLevelEnum.CITY_STAR_THREE.getCode()));
        result.add(weixinTagMap.get(WX_STAR_LEVEL_TAG_PRE + StarLevelEnum.CITY_STAR_FOUR.getCode()));
        result.add(weixinTagMap.get(WX_STAR_LEVEL_TAG_PRE + StarLevelEnum.EC.getCode()));
        result.add(weixinTagMap.get(WX_STAR_LEVEL_TAG_PRE + StarLevelEnum.SEC.getCode()));
        result.add(weixinTagMap.get(WX_STAR_LEVEL_TAG_PRE + StarLevelEnum.EEC.getCode()));
        return result;
    }
}
